package com.tsd.jxc.buy.entity;

import com.tsd.core.constants.Constants;
import com.tsd.core.utils.DoubleUtil;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.utils.ListUtil;
import com.tsd.core.vo.HlpException;
import com.tsd.jxc.JxcConstants;
import com.tsd.jxc.fin.FinanceConstants;
import com.tsd.jxc.fin.entity.JxcFinanceAccountDetailExt;
import com.tsd.jxc.stock.StockConstants;
import com.tsd.jxc.stock.entity.JxcStockInbillExt;
import com.tsd.jxc.stock.entity.JxcStockInbillItemExt;
import com.tsd.jxc.vo.PrintVo;
import com.tsd.system.entity.SysUserExt;
import io.swagger.annotations.ApiModel;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 采购订单扩展
 *
 * @author Hillpool
 * @date 2022/07/29 15:00:45
 */
@ApiModel(description = "采购订单扩展")
public class JxcBuyOrderExt extends JxcBuyOrder implements Serializable {

    /**
     * 审核拒绝
     */
    public static final int AUDIT_STATE_REJECT = -1;
    /**
     * 未审核
     */
    public static final int AUDIT_STATE_UN_AUDIT = 0;
    /**
     * 已审核通过
     */
    public static final int AUDIT_STATE_AUDITED = 1;
    /**
     * 是否生成了入库单 0-否
     */
    public static final int IN_BILL_NO = 0;
    /**
     * 是否生成了入库单 1-部分生成
     */
    public static final int IN_BILL_SECTION = 1;
    /**
     * 是否生成了入库单 2-全部生成
     */
    public static final int IN_BILL_ALL = 2;
    /**
     * 是否生成对账 0-否
     */
    public static final int GEN_FINANCE_NO = 0;
    /**
     * 是否生成对账 1-是
     */
    public static final int GEN_FINANCE_YES = 1;

    private String sys_group_name;

    private String buyer_name;

    private String auditor_person_name;

    private String review_person_name;

    private String supplier_name_join;

    private String supplier_code;

    private String supplier_short_name;

    private String supplier_display;

    private String supplier_contact_name;

    private String supplier_contact_phone;

    private String goods_code;

    private String goods_name;

    private Integer goods_qty;

    private BigDecimal goods_price;

    private BigDecimal goods_amount;

    private Integer goods_return_qty;

    private BigDecimal goods_return_amount;

    private String specifications;

    private List<JxcBuyOrderDetailExt> detail_list;

    private List<String> sid_list;

    private BigDecimal stock_qty;

    private BigDecimal stock_amount;

    public String getSys_group_name() {
        return sys_group_name;
    }

    public void setSys_group_name(String sys_group_name) {
        this.sys_group_name = sys_group_name;
    }

    public String getBuyer_name() {
        return buyer_name;
    }

    public void setBuyer_name(String buyer_name) {
        this.buyer_name = buyer_name;
    }

    public String getAuditor_person_name() {
        return auditor_person_name;
    }

    public void setAuditor_person_name(String auditor_person_name) {
        this.auditor_person_name = auditor_person_name;
    }

    public String getReview_person_name() {
        return review_person_name;
    }

    public void setReview_person_name(String review_person_name) {
        this.review_person_name = review_person_name;
    }

    public String getSupplier_name_join() {
        return supplier_name_join;
    }

    public void setSupplier_name_join(String supplier_name_join) {
        this.supplier_name_join = supplier_name_join;
    }

    public String getSupplier_code() {
        return supplier_code;
    }

    public void setSupplier_code(String supplier_code) {
        this.supplier_code = supplier_code;
    }

    public String getSupplier_short_name() {
        return supplier_short_name;
    }

    public void setSupplier_short_name(String supplier_short_name) {
        this.supplier_short_name = supplier_short_name;
    }

    public String getSupplier_display() {
        return supplier_display;
    }

    public void setSupplier_display(String supplier_display) {
        this.supplier_display = supplier_display;
    }

    public String getSupplier_contact_name() {
        return supplier_contact_name;
    }

    public void setSupplier_contact_name(String supplier_contact_name) {
        this.supplier_contact_name = supplier_contact_name;
    }

    public String getSupplier_contact_phone() {
        return supplier_contact_phone;
    }

    public void setSupplier_contact_phone(String supplier_contact_phone) {
        this.supplier_contact_phone = supplier_contact_phone;
    }

    public String getGoods_code() {
        return goods_code;
    }

    public void setGoods_code(String goods_code) {
        this.goods_code = goods_code;
    }

    public String getGoods_name() {
        return goods_name;
    }

    public void setGoods_name(String goods_name) {
        this.goods_name = goods_name;
    }

    public Integer getGoods_qty() {
        return goods_qty;
    }

    public void setGoods_qty(Integer goods_qty) {
        this.goods_qty = goods_qty;
    }

    public BigDecimal getGoods_price() {
        return goods_price;
    }

    public void setGoods_price(BigDecimal goods_price) {
        this.goods_price = goods_price;
    }

    public BigDecimal getGoods_amount() {
        return goods_amount;
    }

    public void setGoods_amount(BigDecimal goods_amount) {
        this.goods_amount = goods_amount;
    }

    public Integer getGoods_return_qty() {
        return goods_return_qty;
    }

    public void setGoods_return_qty(Integer goods_return_qty) {
        this.goods_return_qty = goods_return_qty;
    }

    public BigDecimal getGoods_return_amount() {
        return goods_return_amount;
    }

    public void setGoods_return_amount(BigDecimal goods_return_amount) {
        this.goods_return_amount = goods_return_amount;
    }

    public String getSpecifications() {
        return specifications;
    }

    public void setSpecifications(String specifications) {
        this.specifications = specifications;
    }

    public List<JxcBuyOrderDetailExt> getDetail_list() {
        return detail_list;
    }

    public void setDetail_list(List<JxcBuyOrderDetailExt> detail_list) {
        this.detail_list = detail_list;
    }

    public List<String> getSid_list() {
        return sid_list;
    }

    public void setSid_list(List<String> sid_list) {
        this.sid_list = sid_list;
    }

    public BigDecimal getStock_qty() {
        return stock_qty;
    }

    public void setStock_qty(BigDecimal stock_qty) {
        this.stock_qty = stock_qty;
    }

    public BigDecimal getStock_amount() {
        return stock_amount;
    }

    public void setStock_amount(BigDecimal stock_amount) {
        this.stock_amount = stock_amount;
    }

    public JxcBuyReturnBillExt genReturnBill() {
        JxcBuyReturnBillExt billExt = new JxcBuyReturnBillExt();
        billExt.setReturn_date(new Date());
        billExt.setSupplier_sid(this.getSupplier_sid());
        billExt.setSupplier_name(this.getSupplier_name_join());
        billExt.setSupplier_code(this.getSupplier_code());
        billExt.setSupplier_short_name(this.getSupplier_short_name());
        billExt.setSupplier_contract_name(this.getSupplier_contract_name());
        billExt.setSupplier_contract_phone(this.getSupplier_contract_phone());
        billExt.setOut_bill(Constants.DR_VALID);
        List<JxcBuyReturnBillDetailExt> detailExtList = ListUtil.map(this.getDetail_list(), JxcBuyOrderDetailExt::genReturnBillDetail);
        detailExtList = ListUtil.filter(detailExtList, t -> !HlpUtils.isEmpty(t.getQty()) && t.getQty().doubleValue() > 0);
        double totalQty = 0D, totalAmount = 0D;
        for (JxcBuyReturnBillDetailExt detailExt : detailExtList) {
            totalQty = DoubleUtil.add(totalQty, detailExt.getQty());
            totalAmount = DoubleUtil.add(totalAmount, detailExt.getAmount());
        }
        billExt.setQty(BigDecimal.valueOf(totalQty));
        billExt.setAmount(BigDecimal.valueOf(totalAmount));
        billExt.setDetail_list(detailExtList);
        return billExt;
    }

    public JxcStockInbillExt genInBill(String warehouse_sid) throws HlpException {
        JxcStockInbillExt inbillExt = new JxcStockInbillExt();
        inbillExt.setWarehouse_sid(warehouse_sid);
        inbillExt.setSrc_sid(this.getSid());
        inbillExt.setSrc_code(this.getCode());
        inbillExt.setIn_type(StockConstants.IN_TYPE_BUY);
        inbillExt.setSupplier_sid(this.getSupplier_sid());
        inbillExt.setIn_date(new Date());
        inbillExt.setAudit_state(Constants.DR_VALID);
        inbillExt.setExecute_state(Constants.DR_VALID);
        List<JxcBuyOrderDetailExt> detailExtList = ListUtil.filter(this.getDetail_list(), t -> !StockConstants.DETAIL_IN_OUT_BILL_ALL.equals(t.getIn_bill()));
        if (detailExtList.isEmpty()) {
            throw new HlpException("没有需要生成入库单的分录");
        }
        List<JxcStockInbillItemExt> itemExtList = ListUtil.map(detailExtList, t -> t.genInBillItem());
        inbillExt.setItem_list(itemExtList);
        inbillExt.setSupplier_sid(detailExtList.get(0).getSupplier_sid());
        return inbillExt;
    }

    public List<JxcStockInbillExt> genInBill4Supplier(String warehouse_sid) throws HlpException {
        List<JxcStockInbillExt> inbillExtList = new ArrayList<>();
        List<String> supplierList = ListUtil.map(this.getDetail_list(), JxcBuyOrderDetailExt::getSupplier_sid);
        for (String supplierSid : supplierList) {
            List<JxcBuyOrderDetailExt> filters = ListUtil.filter(this.getDetail_list(), t -> supplierSid.equals(t.getSupplier_sid()));
            if (HlpUtils.isEmptyList(filters)) {
                continue;
            }
            JxcStockInbillExt inbillExt = new JxcStockInbillExt();
            inbillExt.setWarehouse_sid(warehouse_sid);
            inbillExt.setSrc_sid(this.getSid());
            inbillExt.setSrc_code(this.getCode());
            inbillExt.setIn_type(StockConstants.IN_TYPE_BUY);
            inbillExt.setSupplier_sid(supplierSid);
            inbillExt.setIn_date(new Date());
            inbillExt.setAudit_state(Constants.DR_VALID);
            inbillExt.setExecute_state(Constants.DR_VALID);
            List<JxcBuyOrderDetailExt> detailExtList = ListUtil.filter(filters, t -> !StockConstants.DETAIL_IN_OUT_BILL_ALL.equals(t.getIn_bill()));
            if (detailExtList.isEmpty()) {
                continue;
            }
            List<JxcStockInbillItemExt> itemExtList = ListUtil.map(detailExtList, t -> t.genInBillItem());
            inbillExt.setItem_list(itemExtList);
            inbillExtList.add(inbillExt);
        }
        return inbillExtList;
    }

    public List<JxcFinanceAccountDetailExt> genAccountDetail() {
        List<JxcFinanceAccountDetailExt> list = new ArrayList<>();
        List<String> supplierList = ListUtil.map(this.getDetail_list(), JxcBuyOrderDetailExt::getSupplier_sid);
        for (String supplierSid : supplierList) {
            List<JxcBuyOrderDetailExt> filters = ListUtil.filter(this.getDetail_list(), t -> supplierSid.equals(t.getSupplier_sid()));
            if (HlpUtils.isEmptyList(filters)) {
                continue;
            }
            double totalAmount = 0D;
            for (JxcBuyOrderDetailExt detailExt : filters) {
                totalAmount = DoubleUtil.add(totalAmount, detailExt.getAmount());
            }
            JxcFinanceAccountDetailExt detailExt = new JxcFinanceAccountDetailExt();
            detailExt.setType(FinanceConstants.TYPE_PAYABLE);
            detailExt.setBill_type(FinanceConstants.BILL_TYPE_BUY_ORDER);
            detailExt.setRelated_party_sid(supplierSid);
            detailExt.setThe_date(new Date());
            detailExt.setPayable_amount(BigDecimal.valueOf(totalAmount));
            detailExt.setRelation_sid(this.getSid());
            detailExt.setRelation_code(this.getCode());
            list.add(detailExt);
        }
        if (supplierList.size() == 1) {
            if (!HlpUtils.isEmpty(this.getIgnore_amount()) && this.getIgnore_amount().doubleValue() > 0) {
                JxcFinanceAccountDetailExt ignoreDetailExt = new JxcFinanceAccountDetailExt();
                ignoreDetailExt.setType(FinanceConstants.TYPE_PAYABLE);
                ignoreDetailExt.setBill_type(FinanceConstants.BILL_TYPE_BUY_ORDER_IGNORE);
                ignoreDetailExt.setRelated_party_sid(this.getSupplier_sid());
                ignoreDetailExt.setThe_date(new Date());
                ignoreDetailExt.setPayable_amount(this.getIgnore_amount());
                ignoreDetailExt.setRelation_sid(this.getSid());
                ignoreDetailExt.setRelation_code(this.getCode());
                list.add(ignoreDetailExt);
            }
        }
        return list;
    }

    public PrintVo convert2Print(SysUserExt userExt) {
        PrintVo vo = new PrintVo();
        vo.setCode(this.getCode());
        vo.setCreator_name(this.getCreator_name());
        vo.setCreate_date(this.getCreate_date());
        vo.setAuditor_name(this.getAuditor_name());
        vo.setAudit_date(this.getAudit_date());
        vo.setOrder_date(this.getOrder_date());
        vo.setSupplier_display(this.getSupplier_display());
        vo.setSupplier_contract_name(this.getSupplier_contract_name());
        vo.setSupplier_contract_phone(this.getSupplier_contract_phone());
        vo.setQty(this.getQty());
        vo.setAmount(this.getAmount());
        vo.setPre_freight(this.getPre_freight());
        vo.setReal_freight(this.getReal_freight());
        vo.setFree_shipping(this.getFree_shipping());
        vo.setTotal_amount(this.getTotal_amount());
        vo.setIgnore_amount(this.getIgnore_amount());
        vo.setShould_pay_amount(this.getShould_pay_amount());
        vo.setPaid_amount(this.getPaid_amount());
        vo.setUn_pay_amount(this.getUn_pay_amount());
        vo.setReq_delivery_date(this.getReq_delivery_date());
        vo.setReq_receive_date(this.getReq_receive_date());
        vo.setDelivery_mode(this.getDelivery_mode());
        vo.setBuyer_name(this.getBuyer_name());
        vo.setState(this.getState());
        vo.setReturn_qty(this.getReturn_qty());
        vo.setReturn_amount(this.getReturn_amount());
        vo.setNote_info(this.getNote_info());
        vo.setIn_bill(this.getIn_bill());
        vo.setGen_finance(this.getGen_finance());
        List<PrintVo> detailList = ListUtil.map(this.getDetail_list(), JxcBuyOrderDetailExt::convert2Print);
        vo.setDetail_list(detailList);
        if (userExt != null) {
            vo.setPrint_name(userExt.getName());
        }
        vo.setPrint_datetime(new Date());
        return vo;
    }

    public String getAudit_state_name() {
        if (!HlpUtils.isEmpty(this.getState())) {
            if (this.getAudit_state() == AUDIT_STATE_UN_AUDIT) {
                return "待审核";
            } else if (this.getAudit_state() == AUDIT_STATE_AUDITED) {
                return "已审核";
            } else if (this.getAudit_state() == AUDIT_STATE_REJECT) {
                return "已拒绝";
            }
        }
        return null;
    }

    public String getState_name() {
        if (!HlpUtils.isEmpty(this.getState())) {
            if (this.getState() == com.tsd.core.constants.Constants.VALUE_YES) {
                return "有效";
            } else if (this.getState() == com.tsd.core.constants.Constants.VALUE_NO) {
                return "已作废";
            }
        }
        return null;
    }

    public String getIn_bill_name() {
        if (!HlpUtils.isEmpty(this.getIn_bill())) {
            if (this.getIn_bill() == IN_BILL_NO) {
                return "否";
            } else if (this.getIn_bill() == IN_BILL_SECTION) {
                return "部分生成";
            } else if (this.getIn_bill() == IN_BILL_ALL) {
                return "全部生成";
            }
        }
        return null;
    }

    public String getGen_finance_name() {
        if (!HlpUtils.isEmpty(this.getGen_finance())) {
            if (this.getGen_finance() == GEN_FINANCE_NO) {
                return "否";
            } else if (this.getGen_finance() == GEN_FINANCE_YES) {
                return "是";
            }
        }
        return null;
    }

    public String getInvoice_info() {
        if (!HlpUtils.isEmpty(this.getInvoice_type())) {
            if (this.getInvoice_type() == JxcConstants.INVOICE_TYPE_NO_NEED) {
                return "无进项发票";
            }
            if (this.getInvoice_type() == JxcConstants.INVOICE_TYPE_DZFP) {
                if (JxcConstants.INVOICE_STATE_WAIT == this.getInvoice_state()) {
                    return "待申请【普】";
                }
                if (JxcConstants.INVOICE_STATE_DOING == this.getInvoice_state()) {
                    return "已申请【普】";
                }
                return "已收普票";
            }
            if (this.getInvoice_type() == JxcConstants.INVOICE_TYPE_ZYFP) {
                if (JxcConstants.INVOICE_STATE_WAIT == this.getInvoice_state()) {
                    return "待申请【专】";
                }
                if (JxcConstants.INVOICE_STATE_DOING == this.getInvoice_state()) {
                    return "已申请【专】";
                }
                return "已收专票";
            }
        }
        return null;
    }

    public JxcBuyOrderExt copy() {
        JxcBuyOrderExt orderExt = new JxcBuyOrderExt();
        orderExt.setOrder_date(this.getOrder_date());
        orderExt.setReq_delivery_date(this.getReq_delivery_date());
        orderExt.setReq_receive_date(this.getReq_receive_date());
        orderExt.setReal_receive_date(this.getReal_receive_date());
        orderExt.setDelivery_mode(this.getDelivery_mode());
        orderExt.setFree_shipping(this.getFree_shipping());
        orderExt.setNote_info(this.getNote_info());
        return orderExt;
    }
}
